/* Shared design system for every surface: the public landing page (/), the post-login dashboard
   (/dashboard), the terminal (/terminal) and the operations console (/admin, /login, /setup). Each
   page loads this sheet first and its own layout sheet second (landing.css, dashboard.css,
   workspace.css or portal.css). Tokens are OKLCH; the
   neutrals carry no hue, so cobalt (selection, focus, the one filled button) and cyan (live signal)
   are the only colours on the page besides the three status hues and the compass path identities,
   and every status hue sits beside the word it qualifies. Scales (DESIGN.md § Scales): spacing
   --space-0..6, type --fs-micro..--fs-h1, elevation --shadow-1..3, motion --dur-1..3 with --ease /
   --ease-out / --ease-in-out (no spring easing exists — bounce is rejected by policy). Every
   contrast ratio quoted here was computed (DESIGN.md). The !importants are the [hidden] guard and
   the reduced-motion kill switch, which must beat anything an element also carries. */

@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/ibm-plex-sans-latin-400-normal.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/ibm-plex-sans-latin-500-normal.woff2) format('woff2')}
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/ibm-plex-sans-latin-600-normal.woff2) format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/jetbrains-mono-latin-400-normal.woff2) format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/jetbrains-mono-latin-500-normal.woff2) format('woff2')}
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/jetbrains-mono-latin-600-normal.woff2) format('woff2')}

:root{
 color-scheme:dark;
 --bg:oklch(0.13 0 0);
 --surface:oklch(0.17 0 0);
 --surface-2:oklch(0.21 0 0);
 --surface-3:oklch(0.25 0 0);
 --line:oklch(0.28 0 0);
 --line-strong:oklch(0.36 0 0);
 --text:oklch(0.93 0 0);        /* 15.6:1 on --surface */
 --text-2:oklch(0.74 0 0);      /* 8.3:1 */
 --text-3:oklch(0.62 0 0);      /* 4.8:1 on --surface-2, the floor for 10-11px labels */
 --primary:oklch(0.74 0.14 247);        /* selection, focus, the one filled button. 8.4:1 */
 --primary-ink:oklch(0.13 0 0);         /* 8.8:1 on --primary */
 --primary-hover:oklch(0.80 0.13 247);
 --primary-dim:oklch(0.26 0.05 247);
 --signal:oklch(0.80 0.13 195);         /* live pulse, sparkline tip, tracking price. 10.8:1 */
 --signal-deep:oklch(0.62 0.12 195);    /* sparkline stroke, meter fill. 5.7:1 */
 --signal-track:oklch(0.29 0.04 195);   /* meter track: a lighter step of the same hue */
 --ok:oklch(0.78 0.15 155);--ok-bg:oklch(0.24 0.03 155);--ok-track:oklch(0.29 0.05 155);
 --warn:oklch(0.82 0.14 85);--warn-bg:oklch(0.24 0.03 85);--warn-track:oklch(0.30 0.05 85);
 --bad:oklch(0.72 0.18 25);--bad-bg:oklch(0.24 0.03 25);--bad-track:oklch(0.30 0.06 25);
 /* Workspace colour registry (DESIGN.md): exposure sign and level sources, one hue each, used the same on every chart. Contrast on --surface in brackets. */
 --exp-pos:oklch(0.74 0.12 180);      /* positive exposure, teal (8.8:1) */
 --exp-neg:oklch(0.74 0.15 55);       /* negative exposure, orange (8.0:1) */
 --lvl-iv:oklch(0.74 0.13 300);       /* IV walls (8.0:1) */
 --opt-call:oklch(0.78 0.11 230);     /* call contracts (IV Walls machine); never reused for buyer/seller */
 --opt-put:oklch(0.80 0.13 20);       /* put contracts */
 --lvl-breakout:oklch(0.76 0.13 350); /* breakout zones (8.4:1) */
 --lvl-price-map:oklch(0.80 0.07 95); /* Price Map reach and structure (10.3:1) */
 --lvl-outlook:oklch(0.78 0.04 250);  /* Price Outlook excursion levels (9.6:1) */
 --lvl-reach:oklch(0.72 0 0);         /* historical reach, neutral (7.7:1) */
 --lvl-reference:oklch(0.62 0 0);     /* pivot / reference, neutral (5.3:1) */
  --lvl-balance:oklch(0.78 0.08 215);  /* Balance Map regions and centres (9.4:1) */
  --lvl-reaction:oklch(0.76 0.10 70);  /* Greek reaction zones (8.6:1) */
  --lvl-flow:oklch(0.76 0.09 135);     /* put/call volume balance crossings (8.6:1) */
  --lvl-density:oklch(0.74 0.08 330);  /* density peaks (7.9:1) */
  --lvl-linear-map:oklch(0.80 0.11 80); /* Linear Price Map: vector, bands and imprints in time (10.1:1) */
  --lvl-gray-box:oklch(0.68 0.01 250);  /* Gray Box confluence zones, neutral (6.5:1) */
  --sr-support:oklch(0.74 0.12 155);    /* Relative S/R region below price (green family) */
  --sr-resistance:oklch(0.72 0.15 25);  /* Relative S/R region above price (red family) */
  --sr-at:oklch(0.70 0 0);              /* Relative S/R region at price (neutral) */
  --lvl-dark-pool:oklch(0.70 0.16 285); /* dark-pool prints and levels, blue-violet apart from IV walls (6.9:1) */
  --pressure-lo:oklch(0.26 0.02 60);    /* Pressure Horizon ramp, low end: a warm dark plate tone */
  --pressure-hi:oklch(0.86 0.10 70);    /* Pressure Horizon ramp, high end: one hue, lightness carries the index (10.9:1) */
  --chart-tvc:oklch(0.84 0.13 85);      /* True Volatility Curve and its midpoint reference, gold apart from the H/L greens and reds (11:1) */
 /* Regime identities, ordinal from calm (1) to stressed (5); unknown is neutral. Lightness stays in one
    band so no regime reads louder than another; order is carried by hue and by the label beside it.
    Contrast on --surface: 7.8, 9.2, 10.4, 9.4, 6.7; unknown 4.1 (fills and markers only, never text). */
  --regime-1:oklch(0.72 0.09 250);--regime-2:oklch(0.76 0.08 160);--regime-3:oklch(0.80 0.10 105);
  --regime-4:oklch(0.78 0.12 65);--regime-5:oklch(0.70 0.15 25);--regime-unknown:oklch(0.56 0 0);
 /* Compass favored-path identities (DESIGN.md): violet, orange, teal. Canvas reads them through
    src/chart-layout.js like every other colour. */
 --path-1:#c3a3f5;--path-2:#f79c74;--path-3:#8fd3c8;
 --font-sans:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
 --font-mono:'JetBrains Mono','Cascadia Mono',Consolas,ui-monospace,monospace;
 --radius:4px;--radius-lg:8px;--control:30px;--topbar:48px;
 /* Spacing and type scales. New and edited rules use them; untouched px values converge as rules are edited. */
 --space-0:2px;--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:24px;--space-6:32px;
 --fs-micro:9px;--fs-label:10px;--fs-caption:11px;--fs-ui:12px;--fs-body:13px;--fs-lead:14px;--fs-h3:16px;--fs-h2:18px;--fs-h1:22px;
 /* Elevation: one scale for every floating surface. */
 --shadow-1:0 1px 2px oklch(0 0 0/.35);--shadow-2:0 12px 32px oklch(0 0 0/.5);--shadow-3:0 24px 64px oklch(0 0 0/.6);
 /* Motion: micro (hover), standard (menus, tabs, reveals), structural (layout moves). No spring
    easing anywhere — bounce was considered and rejected; see DESIGN.md § Motion. */
 --dur-1:150ms;--dur-2:200ms;--dur-3:280ms;--dur:var(--dur-2);
 --ease:cubic-bezier(.2,.8,.2,1);--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);
 --z-rail:10;--z-sticky:20;--z-focus:30;--z-menu:35;--z-toast:40;--z-skip:50;
}

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{height:100%;scrollbar-color:var(--line-strong) transparent}
body{margin:0;min-height:100%;background:var(--bg);color:var(--text);font:13px/1.5 var(--font-sans);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
h1,h2,h3,p{margin:0}
h1,h2,h3{text-wrap:balance}
a{color:var(--primary);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
::selection{background:var(--primary-dim);color:var(--text)}
:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.num,time,.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
*{scrollbar-width:thin}

/* ---------- controls: one vocabulary for both pages ---------- */
/* Motion here is state only: a border or fill changing. */
button,input,select,textarea{font:inherit;color:inherit;letter-spacing:inherit}
button{min-height:var(--control);padding:0 11px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface-2);color:var(--text);font-weight:500;cursor:pointer;transition:background-color var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease)}
button:hover{background:var(--surface-3);border-color:var(--text-3)}
button:active{background:var(--surface-2)}
button:disabled{opacity:.45;cursor:default}
button.primary{background:var(--primary);border-color:var(--primary);color:var(--primary-ink);font-weight:600}
button.primary:hover{background:var(--primary-hover);border-color:var(--primary-hover)}
button.danger{color:var(--bad);border-color:var(--bad)}
button.danger:hover{background:var(--bad-bg);border-color:var(--bad)}
/* Ghost buttons: text-only actions and the small square icon actions (⚙ ⛶ × ⓘ). */
.text-button{min-height:24px;padding:0 6px;border-color:transparent;background:transparent;color:var(--text-2)}
.text-button:hover{background:var(--surface-2);color:var(--text);border-color:var(--line)}
.chart-icon-action,.icon-action{min-width:28px;min-height:28px;padding:0 6px;border-color:transparent;background:transparent;color:var(--text-2);font-size:14px;line-height:1}
.chart-icon-action:hover,.icon-action:hover{background:var(--surface-2);color:var(--text);border-color:var(--line)}
.chart-icon-action[aria-expanded=true],.icon-action[aria-expanded=true]{background:var(--surface-2);color:var(--text);border-color:var(--line)}
input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]),select,textarea{width:100%;height:var(--control);padding:0 10px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface-2);color:var(--text);transition:border-color var(--dur) var(--ease)}
input:hover,select:hover,textarea:hover{border-color:var(--text-3)}
input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--primary);outline-offset:0;border-color:var(--primary)}
input::placeholder{color:var(--text-3)}
input:disabled,select:disabled{opacity:.45}
/* Native selects keep their own menu but wear the same box and a hairline chevron. */
select{appearance:none;-webkit-appearance:none;padding-right:26px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23ababab' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 9px center;cursor:pointer}
select option{background:var(--surface-2);color:var(--text)}
input[type=checkbox],input[type=radio]{width:14px;height:14px;margin:0;accent-color:var(--primary);cursor:pointer}
input[type=color]{width:100%;height:28px;padding:2px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface-2);cursor:pointer}
input[type=color]::-webkit-color-swatch-wrapper{padding:0}
input[type=color]::-webkit-color-swatch{border:0;border-radius:2px}
input[type=color]::-moz-color-swatch{border:0;border-radius:2px}
label{display:flex;flex-direction:column;gap:6px;font-size:12px;color:var(--text-2)}
label:has(>input[type=checkbox]),label:has(>input[type=radio]){flex-direction:row;align-items:center;gap:6px;color:var(--text);cursor:pointer}
summary{cursor:pointer;color:var(--text-2);font-weight:500}
summary:hover{color:var(--text)}
details[open]>summary{color:var(--text)}
meter{width:100%;height:3px;border:0;background:var(--signal-track);border-radius:2px;overflow:hidden}
meter::-webkit-meter-bar{background:var(--signal-track);border:0;border-radius:2px}
meter::-webkit-meter-optimum-value,meter::-webkit-meter-suboptimum-value,meter::-webkit-meter-even-less-good-value{background:var(--signal-deep)}
meter::-moz-meter-bar{background:var(--signal-deep)}

/* ---------- topbar ---------- */
.topbar{position:sticky;top:0;z-index:var(--z-sticky);display:flex;align-items:center;justify-content:space-between;gap:12px;height:var(--topbar);padding:0 16px;background:var(--surface);border-bottom:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:10px;font-size:12px;font-weight:600;letter-spacing:.12em;white-space:nowrap}
.brand>div{display:flex;align-items:baseline;gap:10px}
.brandmark{font:600 15px/1 var(--font-mono);color:var(--primary);letter-spacing:0}
.brandmark span{color:var(--signal)}
/* On a signed-in page the brand is the way back to the dashboard: it keeps its own colours, and hover gives it the topbar actions' surface instead of an underline. */
a.brand{color:inherit;margin:-4px -6px;padding:4px 6px;border-radius:var(--radius);transition:background-color var(--dur-1) var(--ease)}
a.brand:hover{text-decoration:none;background:var(--surface-2)}
.subtitle{font-size:10px;font-weight:500;letter-spacing:.14em;color:var(--text-3);padding-left:10px;border-left:1px solid var(--line)}
.top-actions{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.top-actions button,.top-actions a{min-height:30px;padding:0 10px;border:1px solid transparent;border-radius:var(--radius);background:transparent;color:var(--text-2);font-weight:500;line-height:28px}
.top-actions button:hover,.top-actions a:hover{background:var(--surface-2);color:var(--text);text-decoration:none;border-color:var(--line)}
.top-actions button[aria-expanded=true]{background:var(--surface-2);color:var(--text);border-color:var(--line)}
/* Account nav, injected by src/portal-shell.js on the workspace. */
.account-nav{display:flex;align-items:center;gap:4px;padding-left:6px;border-left:1px solid var(--line);margin-left:2px}
.account-name{font:500 11px/1 var(--font-mono);color:var(--text-2);padding:0 6px}
/* The live word is text; the marker beside it pulses only while polling runs. */
.live{display:inline-flex;align-items:center;gap:7px;padding:0 10px 0 6px;font:500 11px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--text-2)}
.live .mark{position:relative}
.live .mark.is-ok::after{content:'';position:absolute;inset:-4px;border-radius:50%;border:1px solid var(--signal);opacity:0;animation:pulse 2.4s var(--ease) infinite}
@keyframes pulse{0%{transform:scale(.4);opacity:.9}70%{transform:scale(1.15);opacity:0}100%{opacity:0}}
body.ops-paused .live .mark::after{animation:none}
/* A badge is a mono word, not a pill: state is carried by the text and an optional marker. */
.badge{display:inline-flex;align-items:center;gap:6px;font:500 10px/1 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--text-2);padding:0 8px;white-space:nowrap}
.badge.is-warn{color:var(--warn)}
.badge.is-bad{color:var(--bad)}

/* ---------- markers ---------- */
/* A marker never carries meaning alone: the word it describes sits beside it and is what a
   screen reader gets. */
.mark,.ops-dot{display:inline-block;flex:none;width:6px;height:6px;border-radius:50%;background:var(--text-3);vertical-align:middle}
.ops-dot{margin-right:6px;vertical-align:baseline;position:relative;top:-1px}
.mark.is-ok,.ops-dot.is-ok{background:var(--ok)}
.mark.is-warn,.ops-dot.is-warn{background:var(--warn)}
.mark.is-bad,.ops-dot.is-bad{background:var(--bad)}
.mark.is-live{background:var(--signal)}

/* ---------- tables ---------- */
.metrics-table{width:100%;border-collapse:collapse;font-size:12px}
.metrics-table th{padding:6px 8px;background:var(--surface-2);font-size:10px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);text-align:left;white-space:nowrap}
.metrics-table th:first-child{border-radius:var(--radius) 0 0 var(--radius)}
.metrics-table th:last-child{border-radius:0 var(--radius) var(--radius) 0}
.metrics-table td{padding:6px 8px;border-top:1px solid var(--line);vertical-align:top;font-variant-numeric:tabular-nums;font-size:12px}
.metrics-table tr:first-child td{border-top:0}
.metrics-table th.num,.metrics-table td.num{text-align:right}
.metrics-table td.num{font-family:var(--font-mono)}
.metrics-table tbody tr{transition:background-color var(--dur) var(--ease)}
.metrics-table tbody tr:hover{background:var(--surface-2)}

/* ---------- chips ---------- */
.chips{display:flex;gap:4px}
.chips button,.chip{min-height:26px;padding:0 10px;border-radius:999px;font-size:11px}
.chips button[aria-pressed=false],.chip[aria-pressed=false]{color:var(--text-3);background:transparent;border-style:dashed}
.chips button[aria-pressed=true],.chip[aria-pressed=true]{background:var(--surface-3);color:var(--text)}

/* ---------- floating surfaces ---------- */
.popover,[popover].popover{position:fixed;inset:auto;margin:0;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius-lg);color:var(--text);box-shadow:var(--shadow-2)}
dialog{background:var(--surface);color:var(--text);border:1px solid var(--line-strong);border-radius:var(--radius-lg);box-shadow:var(--shadow-3)}
dialog[open]{animation:dialog-in var(--dur-2) var(--ease-out)}
@keyframes dialog-in{from{opacity:0;translate:0 8px}}
/* A literal, not a token: ::backdrop does not inherit custom properties in older engines. */
dialog::backdrop{background:rgb(0 0 0/.6)}

/* ---------- toast ---------- */
/* Success and failure must never read the same: wording carries it, and the border agrees. */
.toast{position:fixed;right:16px;bottom:16px;z-index:var(--z-toast);width:fit-content;max-width:min(56ch,calc(100% - 32px));padding:10px 14px;background:var(--surface-2);border:1px solid var(--line-strong);border-radius:var(--radius-lg);font-size:12px;line-height:1.5;box-shadow:var(--shadow-2);transition:opacity var(--dur) var(--ease),translate var(--dur) var(--ease)}
@starting-style{.toast{opacity:0;translate:0 6px}}
.toast:empty{display:none}
.toast.is-ok{border-color:var(--ok);background:var(--ok-bg)}
.toast.is-bad{border-color:var(--bad);background:var(--bad-bg)}

/* ---------- skip link ---------- */
.skip-link{position:fixed;top:-60px;left:12px;z-index:var(--z-skip);padding:8px 12px;background:var(--primary);color:var(--primary-ink);border-radius:var(--radius);font-weight:600}
.skip-link:focus{top:8px;text-decoration:none}

/* ---------- shared responsive ---------- */
@media(max-width:760px){
 :root{--topbar:44px}
 .topbar{height:auto;min-height:var(--topbar);flex-wrap:wrap;padding:4px 12px;row-gap:0}
 .top-actions{margin-left:auto}
 .top-actions button,.top-actions a{padding:0 7px;font-size:12px}
 .live{padding:0 6px 0 4px}
 .subtitle{display:none}
}
@media(pointer:coarse){
 button,select,input:not([type=checkbox]):not([type=radio]):not([type=color]){min-height:40px}
 .top-actions button,.top-actions a,.chips button,.chip{min-height:40px}
}
@media(prefers-reduced-motion:reduce){
 *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
}

/* Light theme, opt-in from the terminal's Layout menu. Neutrals inverted on a warm-free light plate;
   accents darkened so every ratio stays above the AA floor recorded in DESIGN.md. */
:root[data-theme=light]{color-scheme:light;
 --bg:oklch(0.97 0 0);--surface:oklch(0.995 0 0);--surface-2:oklch(0.95 0 0);--surface-3:oklch(0.91 0 0);--line:oklch(0.86 0 0);--line-strong:oklch(0.76 0 0);
 --text:oklch(0.18 0 0);--text-2:oklch(0.36 0 0);--text-3:oklch(0.47 0 0);
 --primary:oklch(0.50 0.16 247);--primary-ink:oklch(0.99 0 0);--primary-hover:oklch(0.44 0.16 247);--primary-dim:oklch(0.90 0.05 247);
 --signal:oklch(0.52 0.12 195);--signal-deep:oklch(0.44 0.11 195);--signal-track:oklch(0.88 0.04 195);
 --ok:oklch(0.48 0.14 155);--ok-bg:oklch(0.93 0.03 155);--ok-track:oklch(0.86 0.05 155);
 --warn:oklch(0.52 0.13 85);--warn-bg:oklch(0.94 0.03 85);--warn-track:oklch(0.86 0.05 85);
 --bad:oklch(0.50 0.18 25);--bad-bg:oklch(0.94 0.03 25);--bad-track:oklch(0.87 0.06 25);
 --path-1:#7d57c1;--path-2:#b35424;--path-3:#2e8b7f;
 --opt-call:oklch(0.50 0.13 230);--opt-put:oklch(0.52 0.16 20);
 --lvl-dark-pool:oklch(0.50 0.18 285);
 --chart-tvc:oklch(0.52 0.12 80);
 --pressure-lo:oklch(0.93 0.02 70);--pressure-hi:oklch(0.50 0.11 55);
 --regime-1:oklch(0.50 0.11 250);--regime-2:oklch(0.50 0.09 160);--regime-3:oklch(0.52 0.10 105);--regime-4:oklch(0.54 0.12 65);--regime-5:oklch(0.50 0.16 25);--regime-unknown:oklch(0.55 0 0);
 --shadow-1:0 1px 2px oklch(0 0 0/.12);--shadow-2:0 12px 32px oklch(0 0 0/.16);--shadow-3:0 24px 64px oklch(0 0 0/.2)}

